package com.maoning.gulimallsearch.thread;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * //关于异步编排的一个测试用例
 * 关于任务完成以后的回调:===>
 * thenRun是不接返回值,直接执行一个任务,没返回值
 * thenAccept是接返回值,但是不在有返回值
 * thenApply是接返回值,也会有返回值
 *
 * runAfterBoth 会组合任务,把.前面的任务和参数里的任务2组合,都完成后执行下一个函数.但无法获取2个前置任务的结果.
 * thenAcceptBoth 也是组合任务,但是可以获取2个任务的返回值.进行处理,没有返回值
 * thenCombineAsync 也是组合任务,可以接返回值,也可以产生返回值.
 *
 * applyToEitherAsync 则是一套关于完成任意1个的处理.
 *
 * 而CompletableFuture.allOf()则是可以组合所有任务.等待所有完成以后处理.
 * anyOf()是任意1个
 *
 * @Author : 猫宁
 * @Date: 2022/2/27
 */
public class ThreadTest {
    public static ExecutorService service = Executors.newFixedThreadPool(10);

    public static void main(String[] args) {
//        ThreadTest.test1();
//        ThreadTest.test2();
        ThreadTest.test3();

    }

    public static void test1(){
        //        System.out.println("thread--main--start");
//        final CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
//            System.out.println(Thread.currentThread().getId());
//            int i = 10 / 2;
//            System.out.println("运行结果=" + i);
//        },service);
//        System.out.println("thread--main--end");



        System.out.println("thread--main--start");
        final CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getId());
            int i = 10 / 0;
            System.out.println("运行结果=" + i);
            return i;
        }, service)
                //方法完成以后的感知
                //可以感知结果,但是不能进行处理
                .whenComplete((r,e) -> {
                    System.out.println("异步任务的结果是:" + r + ",异步任务的异常是:" + e);
                })
                //方法完成以后的感知
                //可以感知异常,同时返回默认值(算是一种处理行为,所以和handler冲突)
//                .exceptionally(e -> {
//            System.out.println("感知到了异常:" + e);
//            //如果这里感知到异常,而且处理了,那么后面的handler就不会处理.
//            return 666;
//        })
                //方法完成以后的处理,可以拿到结果和异常,并且可以修改结果
                .handle((resp,e)->{
                    if(resp != null){
                        return resp;
                    }
                    if(e != null){
                        System.out.println("方法异常了,手动修改异步任务的结果为10");
                        return 10;
                    }
                    return resp;
                });



        System.out.println("thread--main--end");
        try {
            final Integer integer = future.get();
            System.out.println(integer);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

    public static void test2(){

        final CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println(",任务1结束,运行结果=" + i);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return i;
        }, service);

        final CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getId());
            int i = 10 / 5;
            System.out.println("任务2结束,运行结果=" + i);
            return i;
        }, service);

        final CompletableFuture<Void> voidCompletableFuture = future1.thenAcceptBothAsync(future2, (r1, r2) -> {
            System.out.println("1和2结束了才执行3");
            System.out.println(r1);
            System.out.println(r2);
        }, service);
    }

    public static void test3(){

        final CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println(",任务1结束,运行结果=" + i);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return i;
        }, service);

        final CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getId());
            int i = 10 / 5;
            System.out.println("任务2结束,运行结果=" + i);
            return i;
        }, service);

        final CompletableFuture<Integer> integerCompletableFuture = future1.thenCombineAsync(future2, (r1, r2) -> {
            System.out.println("1和2结束了才执行3");
            System.out.println(r1);
            System.out.println(r2);
            return r1 + r2;
        }, service);

        try {
            final Integer integer = integerCompletableFuture.get();
            System.out.println(integer);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }



    }
}
